package com.solution.admin.product.controller;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.solution.admin.customer.entity.CustomerLevelEntity;
import com.solution.admin.customer.service.CustomerLevelService;
import com.solution.admin.home.constants.SequenceConstants.SequenceLength;
import com.solution.admin.home.constants.SequenceConstants.SequenceNameConsts;
import com.solution.admin.home.constants.SequenceConstants.SequenceRedisKey;
import com.solution.admin.home.service.SequenceService;
import com.solution.admin.product.constants.ProductConstants.ProductPriceFieleName;
import com.solution.admin.product.constants.ProductConstants.ProductStatus;
import com.solution.admin.product.entity.ProductCategoryEntity;
import com.solution.admin.product.entity.ProductEntity;
import com.solution.admin.product.entity.ProductImageEntity;
import com.solution.admin.product.entity.ProductPriceEntity;
import com.solution.admin.product.entity.ProductPropertyRelaEntity;
import com.solution.admin.product.entity.ProductRecommendEntity;
import com.solution.admin.product.entity.ProductSpecCompositionEntity;
import com.solution.admin.product.entity.ProductSpecEntity;
import com.solution.admin.product.entity.ProductSpecRelaEntity;
import com.solution.admin.product.entity.ProductTagEntity;
import com.solution.admin.product.entity.PromotionTagEntity;
import com.solution.admin.product.service.ProductCategoryService;
import com.solution.admin.product.service.ProductImageService;
import com.solution.admin.product.service.ProductPriceHistoryService;
import com.solution.admin.product.service.ProductPriceLogService;
import com.solution.admin.product.service.ProductPropertyRelaService;
import com.solution.admin.product.service.ProductPropertyService;
import com.solution.admin.product.service.ProductPropertyTemplateService;
import com.solution.admin.product.service.ProductService;
import com.solution.admin.product.service.ProductSpecCompositionService;
import com.solution.admin.product.service.ProductSpecService;
import com.solution.admin.product.service.ProductTagService;
import com.solution.admin.product.service.ProductUnitService;
import com.solution.admin.product.service.PromotionTagService;
import com.solution.admin.settings.entity.KeyMapEntity;
import com.solution.admin.settings.service.KeyMapService;
import com.solution.admin.settings.service.SortService;
import com.solution.common.config.PublicConfig;
import com.solution.common.config.PublicConfigUtil;
import com.solution.common.constants.PublicStatus.IS_DELETE;
import com.solution.common.constants.PublicStatus.STATUS;
import com.solution.common.constants.PublicStatus.SysCode;
import com.solution.common.constants.PublicStatus.SysSymbol;
import com.solution.common.controller.BaseController;
import com.solution.common.entity.BaseReturn;
import com.solution.common.page.JSONGrid;
import com.solution.common.page.PageBean;
import com.solution.common.page.PageParam;
import com.solution.common.utils.DateUtils;
import com.solution.common.utils.UUIDUtil;
import com.solution.common.utils.importExcel.ExcelUtil;
import com.solution.common.utils.json.JSONUtils;
import com.solution.common.utils.string.StringUtil;
import com.solution.common.utils.upload.OssUploadFile;

/**
 * 商品信息web控制层
 * 
 * @author xu_cc
 * @date 2017-08-29 20:09:14
 */
@RequestMapping("/product")
@Controller
public class ProductController extends BaseController {

	Logger logger = LoggerFactory.getLogger(ProductController.class);

	@Autowired
	ProductService productService;

	@Autowired
	ProductPropertyTemplateService productPropertyTemplateService;

	@Autowired
	ProductPropertyService productPropertyService;

	@Autowired
	ProductPriceLogService productPriceLogService;

	@Autowired
	ProductSpecService productSpecService;

	@Autowired
	ProductSpecCompositionService productSpecCompositionService;

	@Autowired
	ProductPropertyRelaService productPropertyRelaService;

	@Autowired
	ProductImageService productImageService;

	@Autowired
	ProductTagService productTagService;

	@Autowired
	PromotionTagService promotionTagService;

	@Autowired
	ProductUnitService productUnitService;

	@Autowired
	SequenceService sequenceService;

	@Autowired
	CustomerLevelService customerLevelService;

	@Autowired
	ProductPriceHistoryService productPriceHistoryService;

	@Autowired
	ProductCategoryService productCategoryService;

	@Autowired
	KeyMapService keyMapService;

	@Autowired
	private SortService sortService;

	/**
	 * 跳转商品信息查询页面
	 * 
	 * @param Product
	 *            接收界面查询条件参数
	 * @param request
	 *            请求对象
	 * @return 返回对应的页面视图
	 * @author xu_cc
	 * @date 2017-08-29 20:09:14
	 */
	@RequestMapping("/toListProductPage")
	public String toListProductPage(ProductEntity product, HttpServletRequest request) {
		return "product/product_list";
	}

	/**
	 * 根据商品获取规格（传入商品ID，再获取商品分类ID）
	 * 
	 * @Title: doLoadProductSpec
	 * @Description:(描述)
	 * @param request
	 * @param productCategoryId
	 * @return List<ProductSpecEntity>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年10月16日 上午11:52:39
	 */
	@RequestMapping("/doLoadProductSpec")
	@ResponseBody
	public BaseReturn doLoadProductSpec(HttpServletRequest request, Long productId) {
		BaseReturn result = new BaseReturn();
		try {
			if (null != productId) {
				ProductEntity product = productService.getProductById(productId);
				// 获取商品已选中选中规格
				List<ProductSpecRelaEntity> productSpecRelaList = productService.listProductSpecRelaList(productId);
				Long productCategoryId = product.getProductCategoryId();
				// 商品分类对应的所有规格项
				List<ProductSpecEntity> list = productSpecService.listProductSpecByCategoryId(String.valueOf(productCategoryId));
				while (!(null != list && list.size() > 0)) {
					// 如果当前分类未取到规格项，那就取父类的规格
					ProductCategoryEntity productCategory = productCategoryService.getProductCategoryById(productCategoryId);
					if (null != productCategory && null != productCategory.getParentCategoryId()) {
						productCategoryId = productCategory.getParentCategoryId();
						list = productSpecService.listProductSpecByCategoryId(String.valueOf(productCategoryId));
					} else {
						result.setCode(SysCode.FAILED);
						result.setMsg("获取商品规格项失败，该分类及其所属父级分类皆未绑定商品规格项！");
						return result;
					}
				}
				result.setCode(SysCode.SUCCESS);
				// 两个集合一起返回
				Map<String, Object> specMap = new HashMap<String, Object>();
				specMap.put("proSpecList", productSpecRelaList);
				specMap.put("categorySpecList", list);
				result.setData(specMap);
				return result;
			} else {
				result.setCode(SysCode.FAILED);
				result.setMsg("获取商品规格项失败，请先保存商品基本信息！");
				return result;
			}
		} catch (Exception e) {
			result.setCode(SysCode.ERROR);
			result.setMsg("获取商品规格项异常！");
			e.printStackTrace();
			return result;
		}
	}

	/**
	 * 根据传入规格参数组装数据
	 * 
	 * @param request
	 * @param productSpecChose
	 * @return Map<String,Object>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月14日 下午5:42:16
	 */
	@RequestMapping("/doChoseSpecGroup")
	@ResponseBody
	public Map<String, Object> doChoseSpecGroup(HttpServletRequest request, String productSpecChose) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			// productSpecChose =
			// ",显示器#31寸,显示器#32寸,内存#4G,内存#8G,配件#键鼠套装,配件#无配件,处理器#i7 4770K,处理器#i7 6770K,";
			// 拆分传入的选中规格参数【规格名称#规格值,规格名称#规格值,】（显示器#31寸,显示器#32寸,内存#4G,内存#8G,配件#键鼠套装,配件#无配件,处理器#i7
			// 4770K,处理器#i7 6770K,）
			productSpecChose += ",onlineStatus#1";
			String[] proSpecArr = productSpecChose.split(SysSymbol.COMMA);
			Map<String, List<String>> mapList = new HashMap<String, List<String>>();
			// 所有不同规格作为列抽出来，例：["显示器","内存","处理器","配件"]
			Set<String> columns = new HashSet<String>();
			// 数据拆分重组，结果如下：{"显示器":["31寸","32寸"],"内存":["4G","8G"],"处理器":["i7 4770K","i7 6770K"],"配件":["键鼠套装","无配件"]}
			for (String proSpec : proSpecArr) {
				if (StringUtil.isNotNull(proSpec) && proSpec.contains(SysSymbol.NUMBER_SIGN)) {
					String[] specArr = proSpec.split(SysSymbol.NUMBER_SIGN);
					String key = specArr[0];
					columns.add(key);
					String spec = specArr[1];
					if (mapList.containsKey(specArr[0])) {
						mapList.get(key).add(spec);
					} else {
						List<String> specList = new ArrayList<String>();
						specList.add(spec);
						mapList.put(key, specList);
					}
				}
			}
			/* 数据组装 */
			List<Map<String, String>> totalMapList = new ArrayList<Map<String, String>>();
			for (Map.Entry<String, List<String>> entry : mapList.entrySet()) {
				totalMapList = doUnionAll(totalMapList, entry.getKey(), entry.getValue());
			}
			resultMap.put("code", 1);
			resultMap.put("columns", columns);
			resultMap.put("rows", totalMapList);
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", -1);
			resultMap.put("msg", "组装规格数据异常！");
		}
		return resultMap;
	}

	/**
	 * 数据合并<br/>
	 * 组装前数据：<br/>
	 * {"显示器":["31寸","32寸"],<br/>
	 * "内存":["4G","8G"],<br/>
	 * "处理器":["i7 4770K","i7 6770K"],<br/>
	 * "配件":["键鼠套装","无配件"]}<br/>
	 * <br/>
	 * 组装后数据：<br/>
	 * {"显示器":"31寸","内存":"4G","处理器":"i7 4770K","配件":"键鼠套装"}<br/>
	 * {"显示器":"31寸","内存":"4G","处理器":"i7 4770K","配件":"无配件"}<br/>
	 * {"显示器":"31寸","内存":"4G","处理器":"i7 6770K","配件":"键鼠套装"}<br/>
	 * {"显示器":"31寸","内存":"4G","处理器":"i7 6770K","配件":"无配件"}<br/>
	 * {"显示器":"31寸","内存":"8G","处理器":"i7 4770K","配件":"键鼠套装"}<br/>
	 * {"显示器":"31寸","内存":"8G","处理器":"i7 4770K","配件":"无配件"}<br/>
	 * {"显示器":"31寸","内存":"8G","处理器":"i7 6770K","配件":"键鼠套装"}<br/>
	 * {"显示器":"31寸","内存":"8G","处理器":"i7 6770K","配件":"无配件"}<br/>
	 * {"显示器":"32寸","内存":"4G","处理器":"i7 4770K","配件":"键鼠套装"}<br/>
	 * {"显示器":"32寸","内存":"4G","处理器":"i7 4770K","配件":"无配件"}<br/>
	 * {"显示器":"32寸","内存":"4G","处理器":"i7 6770K","配件":"键鼠套装"}<br/>
	 * {"显示器":"32寸","内存":"4G","处理器":"i7 6770K","配件":"无配件"}<br/>
	 * {"显示器":"32寸","内存":"8G","处理器":"i7 4770K","配件":"键鼠套装"}<br/>
	 * {"显示器":"32寸","内存":"8G","处理器":"i7 4770K","配件":"无配件"}<br/>
	 * {"显示器":"32寸","内存":"8G","处理器":"i7 6770K","配件":"键鼠套装"}<br/>
	 * {"显示器":"32寸","内存":"8G","处理器":"i7 6770K","配件":"无配件"}
	 * 
	 * @param totalMapList
	 * @param key
	 * @param childList
	 * @return List<Map<String,String>>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月14日 下午5:24:40
	 */
	public static List<Map<String, String>> doUnionAll(List<Map<String, String>> totalMapList, String key, List<String> childList) {
		try {
			if (null != totalMapList && totalMapList.size() > 0) {
				if (null != childList && childList.size() > 0) {
					List<Map<String, String>> newMapList = new ArrayList<Map<String, String>>();
					for (Map<String, String> oldMap : totalMapList) {
						for (String childItem : childList) {
							Map<String, String> newMap = new HashMap<String, String>();
							newMap.putAll(oldMap);
							newMap.put(key, childItem);
							newMapList.add(newMap);
						}
					}
					totalMapList = newMapList;
				}
			} else {
				if (null != childList && childList.size() > 0) {
					Map<String, String> map = null;
					for (String item : childList) {
						map = new HashMap<String, String>();
						map.put(key, item);
						totalMapList.add(map);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return totalMapList;
	}

	/**
	 * 获取价格列表
	 * 
	 * @Title: getPriceList
	 * @Description:(描述)
	 * @param productId
	 * @return JSONGrid
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月3日 下午1:44:23
	 */
	@RequestMapping("/getPriceList")
	@ResponseBody
	public JSONGrid getPriceList(String productId) {
		JSONGrid reGrid = null;
		try {
			if (StringUtil.isNotNull(productId)) {
				List<ProductPriceEntity> priceList = productService.getProductPriceList(Long.parseLong(productId));
				reGrid = new JSONGrid(priceList, priceList.size());
			} else {
				reGrid = new JSONGrid();
				return reGrid;
			}
		} catch (Exception e) {
			e.printStackTrace();
			reGrid = new JSONGrid();
		}
		return reGrid;
	}

	/**
	 * 获取各级别价格历史信息
	 * 
	 * @param request
	 * @param productId
	 * @param priceLevel
	 * @return JSONGrid
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年12月12日 上午11:12:31
	 */
	@RequestMapping("/getPriceHistoryList")
	@ResponseBody
	public JSONGrid getPriceHistoryList(HttpServletRequest request, String productId, String priceLevel) {
		try {
			int pageNum = Integer.parseInt(request.getParameter("page").toString());
			int numPerPage = Integer.parseInt(request.getParameter("rows").toString());
			PageParam pageParam = super.getPageParam(request);
			pageParam.setPageNum(pageNum);
			pageParam.setNumPerPage(numPerPage);
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("productId", productId);
			paramMap.put("customerLevel", priceLevel);
			PageBean pageBean = productPriceHistoryService.listProductPriceHistoryPage(pageParam, paramMap);
			return new JSONGrid(pageBean.getRecordList(), pageBean.getTotalCount());
		} catch (Exception e) {
			e.printStackTrace();
			return new JSONGrid();
		}
	}

	/**
	 * 价格日志
	 * 
	 * @Title: getPriceLogList
	 * @Description:(描述)
	 * @param request
	 * @param productId
	 * @return JSONGrid
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月3日 下午4:18:25
	 */
	@RequestMapping("/getPriceLogList")
	@ResponseBody
	public JSONGrid getPriceLogList(HttpServletRequest request, String productId, String type) {
		int pageNum = Integer.parseInt(request.getParameter("page").toString());
		int numPerPage = Integer.parseInt(request.getParameter("rows").toString());
		PageParam pageParam = super.getPageParam(request);
		pageParam.setPageNum(pageNum);
		pageParam.setNumPerPage(numPerPage);
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("productId", productId);
		if (type.equals("1")) {
			// 基价
			paramMap.put("fieldName", ProductPriceFieleName.BASE_PRICE);
		} else {
			// 模拟成本
			paramMap.put("fieldName", ProductPriceFieleName.LOG_FIELD_NAME);
		}
		try {
			PageBean pageBean = productPriceLogService.listProductPriceLogPage(pageParam, paramMap);
			return new JSONGrid(pageBean.getRecordList(), pageBean.getTotalCount());
		} catch (Exception e) {
			handleException("分页查询商品信息失败", logger, e);
		}
		return new JSONGrid();
	}

	/**
	 * 分页查询关联商品
	 * 
	 * @param request
	 * @param productId
	 * @param type
	 * @return JSONGrid
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月17日 下午3:32:35
	 */
	@RequestMapping("/listProductRela")
	@ResponseBody
	public JSONGrid listProductRela(HttpServletRequest request, Long productId, String type, String productCode, String productName,
	        String productCategoryId) {
		try {
			if (null == productId) {
				return new JSONGrid();
			}
			List<ProductEntity> productList = productService.listProductRela(productId, type, productCode, productName, productCategoryId);
			return new JSONGrid(productList, productList.size());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new JSONGrid();
	}
	
	/**
	 * 跳转至商品选择器
	 * @param request
	 * @return
	 */
	@RequestMapping("/toProductSelector")
	public String toProductSelector(HttpServletRequest request){
		return "/coupon/product_selector";
	}

	/**
	 * 分页查询商品信息列表
	 * 
	 * @param product
	 *            接收界面查询条件参数
	 * @param request
	 *            请求对象
	 * @return 返回对应的页面视图
	 * @author xu_cc
	 * @date 2017-08-29 20:09:14
	 */
	@RequestMapping("/listProductPage")
	@ResponseBody
	public JSONGrid listProductPage(ProductEntity product, HttpServletRequest request) {
		int pageNum = Integer.parseInt(request.getParameter("page").toString());
		int numPerPage = Integer.parseInt(request.getParameter("rows").toString());
		PageParam pageParam = super.getPageParam(request);
		pageParam.setPageNum(pageNum);
		pageParam.setNumPerPage(numPerPage);
		try {
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("productCode", product.getProductCode());
			paramMap.put("productName", product.getProductName());
			paramMap.put("brandCode", product.getBrandCode());
			paramMap.put("productCategoryId", product.getProductCategoryId());
			// paramMap.put("productTag", product.getProductTag());
			paramMap.put("promotionTag", product.getPromotionTag());
			paramMap.put("productStatus", product.getProductStatus());
			paramMap.put("productType", product.getProductType());
			PageBean pageBean = productService.listProductPage(pageParam, paramMap);
			return new JSONGrid(pageBean.getRecordList(), pageBean.getTotalCount());
		} catch (Exception e) {
			handleException("分页查询商品信息失败", logger, e);
		}
		return new JSONGrid();
	}

	/**
	 * 活动商品选择
	 * 
	 * @param product
	 * @param request
	 * @return JSONGrid
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月28日 下午7:47:15
	 */
	@RequestMapping("/listProPage")
	@ResponseBody
	public JSONGrid listProPage(HttpServletRequest request, String type, String categoryCode, String brandCode, String childBrandCode,
	        String productName) {
		int pageNum = Integer.parseInt(request.getParameter("page").toString());
		int numPerPage = Integer.parseInt(request.getParameter("rows").toString());
		PageParam pageParam = super.getPageParam(request);
		pageParam.setPageNum(pageNum);
		pageParam.setNumPerPage(numPerPage);
		try {
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("type", type);
			paramMap.put("productName", productName);
			paramMap.put("brandCode", brandCode);
			paramMap.put("childBrandCode", childBrandCode);
			paramMap.put("categoryCode", categoryCode);
			PageBean pageBean = productService.listProductForPromotionPage(pageParam, paramMap);
			return new JSONGrid(pageBean.getRecordList(), pageBean.getTotalCount());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new JSONGrid();
	}

	/**
	 * 跳转新增页面
	 * 
	 * @return string 跳转页面路径
	 * @author xu_cc
	 * @date 2017-08-29 20:09:14
	 */
	@RequestMapping("/toAddProduct")
	public String toAddProduct(HttpServletRequest request, Model model) {
		request.setAttribute("opFlag", "add");
		try {
			// 序列号
			String seqCode = sequenceService.getSequenceNumber(SequenceRedisKey.REDIS_SEQ_PRODUCT, SequenceLength.LENGTH_PRODUCT);
			// 商品编码
			String productCode = SequenceNameConsts.SEQ_PRODUCT.concat(seqCode);
			ProductEntity product = new ProductEntity();
			product.setProductCode(productCode);
			model.addAttribute("product", product);
			// 商品标签
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("status", STATUS.ENABLED.getId());
			List<ProductTagEntity> productTagList = productTagService.listProductTag(param);
			model.addAttribute("productTagList", productTagList);
			// 活动标签.
			List<PromotionTagEntity> promotionTagList = promotionTagService.listPromotionTag(param);
			model.addAttribute("promotionTagList", promotionTagList);
			// 商品状态
			List<KeyMapEntity> productStatusList = keyMapService.listKeyMap("productStatus");
			model.addAttribute("productStatusList", productStatusList);
			// 组装规格数据
			model.addAttribute("productSpecMap", doGetProductSpec());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "product/product_form";
	}

	/**
	 * 添加商品基本信息
	 * 
	 * @Title: addProductBase
	 * @Description:(描述)
	 * @param request
	 * @param product
	 * @return Map<String,Object>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月1日 下午5:40:46
	 */
	@RequestMapping(value = "/addProductBase")
	@ResponseBody
	public Map<String, Object> saveProductBase(HttpServletRequest request, ProductEntity product, String properties, String propertyTmeplateId) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			/* 积分商品所属商品分类 */
			String pointProductCategoryIdStr = PublicConfigUtil.readConfig("point.product.category.id");
			product.setIsPointProduct(0);
			if(StringUtil.isNotNull(pointProductCategoryIdStr)) {
				Long pointProductCategoryId = Long.parseLong(pointProductCategoryIdStr);
				ProductCategoryEntity productCategory = productCategoryService.getProductCategoryById(product.getProductCategoryId());
				if(null != productCategory && (productCategory.getId().equals(pointProductCategoryId) || productCategory.getParentCategoryId().equals(pointProductCategoryId))) {
					product.setIsPointProduct(1);
				}
			}
			
			product.setCreater(getUserName());
			product.setModifier(getUserName());
			product.setIsDelete(IS_DELETE.NORMAL.getId());
			product.setStatus(STATUS.ENABLED.getId());
			product.setProductType(1);
			product.setProductMerchantId(1);
			product.setPropertyTmeplateId(propertyTmeplateId);
			if (StringUtil.isEmpty(product.getProductName())) {
				resultMap.put("code", "0");
				resultMap.put("msg", "请输入商品名称！");
				return resultMap;
			}
			// 判断名称是否重复
			// 已存在商品的ID
			Long existsProductId = null;
			String existsProductCode = null;
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("eqProductName", product.getProductName());
			List<ProductEntity> proList = productService.listProduct(param);
			if (null != proList && proList.size() > 0) {
				existsProductId = proList.get(0).getId();
				existsProductCode = proList.get(0).getProductCode();
			}
			if (null == product.getId()) {
				// 保存
				if (null != existsProductId) {
					resultMap.put("code", "0");
					resultMap.put("msg", "保存失败！该商品已存在！<br>商品编码 ：" + existsProductCode);
					return resultMap;
				} else {
					product.setPointExchangeRate(BigDecimal.ZERO);
					product.setPointCieffucuebt(BigDecimal.ZERO);
					product.setProductStatus(ProductStatus.STATUS_OFFLINE);
					if(product.getIsPointProduct().equals(0)) {
						//最小
						int sortNo = sortService.getFirstSortNo("EB_PRODUCT");
						product.setSortNo(sortNo);// 默认排序号
						// 最大
						int quatoSortNo = sortService.getMaxSortNo("EB_PRODUCT");
						product.setQuotaSortNo(quatoSortNo);
					} else {
						// 最大
						int sortNo = sortService.getMaxSortNo("EB_PRODUCT");
						product.setSortNo(sortNo);// 默认排序号
						product.setQuotaSortNo(sortNo);
					}
					productService.saveProduct(product);
				}
			} else {
				// 修改，看是不是自己（未找到已有数据）
				if (null == existsProductId || product.getId().equals(existsProductId)) {
					// 是自己
					productService.updateProductBase(product);
				} else {
					// 别的商品
					resultMap.put("code", "0");
					resultMap.put("msg", "保存失败！其他商品已使用该商品名称！<br>商品编码 ：" + existsProductCode);
					return resultMap;
				}
			}
			resultMap.put("code", "1");
			resultMap.put("productId", product.getId());
			resultMap.put("msg", "商品基本信息保存成功！");
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "0");
			resultMap.put("msg", "商品基本信息保存异常，请重试！");
		}
		return resultMap;
	}

	/**
	 * 组装规格数据
	 * 
	 * @return Map<String,List<ProductSpecEntity>>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月14日 上午12:22:04
	 */
	private Map<String, List<ProductSpecEntity>> doGetProductSpec() {
		Map<String, List<ProductSpecEntity>> map = new HashMap<String, List<ProductSpecEntity>>();
		try {
			List<ProductSpecEntity> productSpecList = productSpecService.listProductSpec(new HashMap<String, Object>());
			if (null != productSpecList && productSpecList.size() > 0) {
				List<ProductSpecEntity> childSpecList = null;
				for (ProductSpecEntity productSpec : productSpecList) {
					if (map.containsKey(productSpec.getSpecName())) {
						map.get(productSpec.getSpecName()).add(productSpec);
					} else {
						childSpecList = new ArrayList<ProductSpecEntity>();
						childSpecList.add(productSpec);
						map.put(productSpec.getSpecName(), childSpecList);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * 保存规格设置信息
	 * 
	 * @param request
	 * @param productId
	 * @param productSpecChose
	 *            (规格名称#规格值#规格值ID,规格名称#规格值#规格值ID)
	 * @param specRows
	 * @return Map<String,Object>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月16日 下午2:06:08
	 */
	@RequestMapping(value = "/saveProductNorms")
	@ResponseBody
	public Map<String, Object> saveProductNorms(HttpServletRequest request, Long productId, String productSpecChose, String specRows) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		// 规格名称#规格值#规格值ID#价格
		// gogo#解甲归田#144,gogo#来来去增#145,测试111#王#114,
		try {
			if (null == productId) {
				resultMap.put("code", "0");
				resultMap.put("msg", "请先保存商品基本信息！");
				return resultMap;
			}
			if (StringUtil.isEmpty(productSpecChose) || StringUtil.isEmpty(specRows)) {
				resultMap.put("code", "0");
				resultMap.put("msg", "请先选择规格信息！");
				return resultMap;
			}
			String currentUserCode = getUserName();
			/* 商品规格选择 */
			List<ProductSpecRelaEntity> productSpecRelaList = new ArrayList<ProductSpecRelaEntity>();
			// 根据逗号按照行获取规格信息
			ProductSpecRelaEntity productSpecRela = null;
			String[] specRowArr = productSpecChose.split(SysSymbol.COMMA);
			if (null != specRowArr && specRowArr.length > 0) {
				for (int i = 0; i < specRowArr.length; i++) {
					String specRow = specRowArr[i];
					if (StringUtil.isNotNull(productSpecChose) && specRow.indexOf(SysSymbol.NUMBER_SIGN) >= 0) {
						String[] specArr = specRow.split(SysSymbol.NUMBER_SIGN);
						if (null != specArr && specArr.length >= 3) {
							productSpecRela = new ProductSpecRelaEntity();
							productSpecRela.setProductId(Integer.parseInt(String.valueOf(productId)));
							productSpecRela.setSpecName(specArr[0]);
							productSpecRela.setSpecValue(specArr[1]);
							productSpecRela.setSpecId(Integer.parseInt(specArr[2]));
							productSpecRela.setSortNo(i);
							productSpecRela.setCreater(currentUserCode);
							productSpecRela.setModifier(currentUserCode);
							productSpecRelaList.add(productSpecRela);
						}
					}
				}
			}
			/* 规格组装集合 */
			List<ProductSpecCompositionEntity> productSpecCompositionList = new ArrayList<ProductSpecCompositionEntity>();
			/** 解析规格组合 */
			JSONArray array = JSONArray.parseArray(specRows);
			JSONObject jsonObj = null;
			ProductSpecCompositionEntity specComposition = null;
			for (int j = 0; j < array.size(); j++) {
				jsonObj = array.getJSONObject(j);
				specComposition = new ProductSpecCompositionEntity();
				specComposition.setId(jsonObj.containsKey("id") ? jsonObj.getLong("id") : null);
				specComposition.setProductId(Integer.parseInt(String.valueOf(productId)));
				specComposition.setSpecComposition(JSONUtils.toJsonString(jsonObj));
				specComposition.setOnlineStatus(jsonObj.getIntValue("onlineStatus"));
				specComposition.setCreater(currentUserCode);
				specComposition.setModifier(currentUserCode);
				productSpecCompositionList.add(specComposition);
			}
			int rows = 0;
			if (productSpecCompositionList.size() > 0 && productSpecRelaList.size() > 0) {
				rows = productService.saveProductSpecComposition(productId, productSpecRelaList, productSpecCompositionList);
			}
			resultMap.put("code", (rows > 0) ? 1 : 0);
			resultMap.put("msg", (rows > 0) ? "保存商品规格信息成功！" : "保存商品规格信息失败！");
			return resultMap;

		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "-1");
			resultMap.put("msg", "保存商品规格信息异常！");
			return resultMap;
		}
	}

	/**
	 * 商品图文描述
	 * 
	 * @Title: saveProductDesc
	 * @Description:(描述)
	 * @param request
	 * @param product
	 * @return Map<String,Object>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月3日 下午6:58:24
	 */
	@RequestMapping(value = "/saveProductDesc")
	@ResponseBody
	public Map<String, Object> saveProductDesc(HttpServletRequest request, ProductEntity product) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			productService.updateProduct(product);
			if (product.getProductImgStr().contains(SysSymbol.NUMBER_SIGN) && product.getProductImgStr().length() > 10) {
				// 先删除
				productImageService.deleteByProductId(product.getId(), null);
				String[] productImgArr = product.getProductImgStr().split(SysSymbol.NUMBER_SIGN);
				ProductImageEntity productImage = null;
				for (int i = 0; i < productImgArr.length; i++) {
					String path = productImgArr[i];
					if (StringUtil.isNotNull(path)) {
						productImage = new ProductImageEntity();
						if (i == 0) {
							// 设置主图
							productImage.setImageType(1);
						} else {
							productImage.setImageType(0);
						}
						productImage.setProductId(Integer.parseInt(String.valueOf(product.getId())));
						productImage.setImagePath(path);
						productImage.setCreater(getUserName());
						productImageService.saveProductImage(productImage);
					}
				}
			}
			resultMap.put("code", "1");
			resultMap.put("msg", "商品图文信息保存成功！");
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "0");
			resultMap.put("msg", "商品图文信息保存异常，请重试！");
		}
		return resultMap;
	}

	/**
	 * 保存价格模块
	 * 
	 * @Title: saveProductPrice
	 * @Description:(描述)
	 * @param request
	 * @param product
	 * @return Map<String,Object>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月3日 下午4:14:59
	 */
	@RequestMapping(value = "/saveProductPrice")
	@ResponseBody
	public Map<String, Object> saveProductPrice(HttpServletRequest request, ProductEntity product) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			product.setModifier(getUserName());
			productService.updateProductPrice(product);
			resultMap.put("code", "1");
			resultMap.put("msg", "商品价格信息保存成功！");
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "0");
			resultMap.put("msg", "商品价格信息保存异常，请重试！");
		}
		return resultMap;
	}

	/**
	 * 商品上下架状态及关联商品保存
	 * 
	 * @param request
	 * @param id
	 * @param onlineStatus
	 * @param relaRows
	 * @return Map<String,Object>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月17日 下午6:53:45
	 */
	@RequestMapping("/saveProductRela")
	@ResponseBody
	public Map<String, Object> saveProductRela(HttpServletRequest request, 
			Long id, 
			Integer productStatus, 
			Integer isQuato, 
			String depositDeliveryDay,
			Integer sortWeight, 
			String relaRows,
			String touristVisible) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			// 商品上架/预售，校验价格信息是否完整
			if (ProductStatus.STATUS_ONLINE.equals(productStatus) || ProductStatus.STATUS_PRESELL.equals(productStatus)) {
				// 校验价格信息是否维护完成
				ProductEntity product = productService.getProductById(id);
				if (null == product.getBasePrice()) {
					resultMap.put("code", "0");
					resultMap.put("msg", "未维护商品价格！");
					return resultMap;
				}
				List<ProductPriceEntity> priveList = productService.getProductPriceList(id);
				Map<String, Object> param = new HashMap<String, Object>();
				param.put("isDelete", IS_DELETE.NORMAL.getId());
				List<CustomerLevelEntity> levelList = customerLevelService.listEbCustomerLevel(param);
				// 多少个客户级别
				int levelCount = (null != levelList ? levelList.size() : 0);
				if (null == priveList || priveList.size() < levelCount) {
					// 未获取到各级别价格，或者获取的价格少于级别数，说明有的级别还是未设置价格
					resultMap.put("code", "0");
					resultMap.put("msg", "请为所有的客户级别设置商品价格！");
					return resultMap;
				}
				// 校验商品主图有没有
				List<ProductImageEntity> imgList = productImageService.listProductImage(product.getId(), "1");
				if (!(null != imgList && imgList.size() > 0)) {
					// 未获取到各级别价格，或者获取的价格少于级别数，说明有的级别还是未设置价格
					resultMap.put("code", "0");
					resultMap.put("msg", "请上传商品图片信息！");
					return resultMap;
				}
			}
			String userCode = getUserName();
			List<ProductRecommendEntity> productRelaList = null;
			if (StringUtil.isNotNull(relaRows)) {
				productRelaList = new ArrayList<ProductRecommendEntity>();
				JSONArray array = JSONArray.parseArray(relaRows);
				JSONObject jsonObj = null;
				ProductRecommendEntity productRela = null;
				for (int j = 0; j < array.size(); j++) {
					jsonObj = array.getJSONObject(j);
					productRela = new ProductRecommendEntity();
					productRela.setCreater(userCode);
					productRela.setProductId(Integer.parseInt(String.valueOf(id)));
					productRela.setProductRelaId(jsonObj.getIntValue("id"));
					productRelaList.add(productRela);
				}
			}
			ProductEntity product = new ProductEntity();
			product.setId(id);
			product.setSortWeight(sortWeight);
			product.setProductStatus(productStatus);
			product.setIsQuato(isQuato);
			product.setProductRelaList(productRelaList);
			product.setTouristVisible(touristVisible);
			if(StringUtil.isNotNull(depositDeliveryDay)) {
				product.setDepositDeliveryDay(DateUtils.parseDate(depositDeliveryDay));
			}
			product.setModifier(userCode);
			int rows = productService.updateProduct(product);
			if (rows > 0) {
				resultMap.put("code", "1");
				resultMap.put("msg", "商品上下架状态及关联商品保存成功！");
			} else {
				resultMap.put("code", "0");
				resultMap.put("msg", "商品上下架状态及关联商品保存失败！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "-1");
			resultMap.put("msg", "商品上下架状态及关联商品保存异常！");
		}
		return resultMap;
	}

	/**
	 * 修改上下架状态
	 * 
	 * @param request
	 * @param productId
	 * @param onlineStatus
	 * @return Map<String,Object>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月13日 下午2:19:13
	 */
	@RequestMapping("/modifyOnlineStatus")
	@ResponseBody
	public Map<String, Object> modifyOnlineStatus(HttpServletRequest request, Long productId, Integer onlineStatus) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			if (StringUtil.isNotNull(productId)) {
				// 商品上架，校验价格信息是否完整
				if (ProductStatus.STATUS_ONLINE.equals(onlineStatus) || ProductStatus.STATUS_PRESELL.equals(onlineStatus)) {
					// 校验价格信息是否维护完成
					ProductEntity product = productService.getProductById(productId);
					if (null == product.getBasePrice()) {
						resultMap.put("code", "0");
						resultMap.put("msg", "未维护商品价格！");
						return resultMap;
					}
					List<ProductPriceEntity> priveList = productService.getProductPriceList(productId);
					Map<String, Object> param = new HashMap<String, Object>();
					param.put("isDelete", IS_DELETE.NORMAL.getId());
					List<CustomerLevelEntity> levelList = customerLevelService.listEbCustomerLevel(param);
					// 多少个客户级别
					int levelCount = (null != levelList ? levelList.size() : 0);
					if (null == priveList || priveList.size() < levelCount) {
						// 未获取到各级别价格，或者获取的价格少于级别数，说明有的级别还是未设置价格
						resultMap.put("code", "0");
						resultMap.put("msg", "请为所有的客户级别设置商品价格！");
						return resultMap;
					}
					// 校验商品主图有没有
					List<ProductImageEntity> imgList = productImageService.listProductImage(product.getId(), "1");
					if (!(null != imgList && imgList.size() > 0)) {
						// 未获取到各级别价格，或者获取的价格少于级别数，说明有的级别还是未设置价格
						resultMap.put("code", "0");
						resultMap.put("msg", "请上传商品图片信息！");
						return resultMap;
					}
				}
				ProductEntity productEntity = new ProductEntity();
				productEntity.setId(productId);
				productEntity.setProductStatus(new Integer(onlineStatus));
				productEntity.setModifier(getUserName());
				int rows = productService.updateProduct(productEntity);
				if (rows > 0) {
					resultMap.put("code", "1");
					resultMap.put("msg", "商品上下架状态更新成功！");
				} else {
					resultMap.put("code", "0");
					resultMap.put("msg", "商品上下架状态更新失败！");
				}
			} else {
				resultMap.put("code", "0");
				resultMap.put("msg", "商品上下架状态更新失败，请重试！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "-1");
			resultMap.put("msg", "商品上下架状态更新失败，请重试！");
		}
		return resultMap;
	}

	/**
	 * 修改商品状态
	 * 
	 * @param request
	 * @param productId
	 * @param onlineStatus
	 * @return Map<String,Object>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2018年1月1日 上午11:08:27
	 */
	@RequestMapping("/modifyProductStatus")
	@ResponseBody
	public Map<String, Object> modifyProductStatus(HttpServletRequest request, Long productId, Integer productStatus) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			if (StringUtil.isNotNull(productId)) {
				// 商品上架/预售，校验价格信息是否完整
				if (ProductStatus.STATUS_ONLINE.equals(productStatus) || ProductStatus.STATUS_PRESELL.equals(productStatus)) {
					// 校验价格信息是否维护完成
					ProductEntity product = productService.getProductById(productId);
					if (null == product.getBasePrice()) {
						resultMap.put("code", "0");
						resultMap.put("msg", "未维护商品价格！");
						return resultMap;
					}
					List<ProductPriceEntity> priveList = productService.getProductPriceList(productId);
					Map<String, Object> param = new HashMap<String, Object>();
					param.put("isDelete", IS_DELETE.NORMAL.getId());
					List<CustomerLevelEntity> levelList = customerLevelService.listEbCustomerLevel(param);
					// 多少个客户级别
					int levelCount = (null != levelList ? levelList.size() : 0);
					if (null == priveList || priveList.size() < levelCount) {
						// 未获取到各级别价格，或者获取的价格少于级别数，说明有的级别还是未设置价格
						resultMap.put("code", "0");
						resultMap.put("msg", "请为所有的客户级别设置商品价格！");
						return resultMap;
					}
					// 校验商品主图有没有
					List<ProductImageEntity> imgList = productImageService.listProductImage(product.getId(), "1");
					if (!(null != imgList && imgList.size() > 0)) {
						// 未获取到各级别价格，或者获取的价格少于级别数，说明有的级别还是未设置价格
						resultMap.put("code", "0");
						resultMap.put("msg", "请上传商品图片信息！");
						return resultMap;
					}
				}

				ProductEntity productEntity = new ProductEntity();
				productEntity.setId(productId);
				productEntity.setProductStatus(productStatus);
				productEntity.setModifier(getUserName());
				int rows = productService.updateProduct(productEntity);
				if (rows > 0) {
					resultMap.put("code", "1");
					resultMap.put("msg", "商品状态更新成功！");
				} else {
					resultMap.put("code", "0");
					resultMap.put("msg", "商品状态更新失败！");
				}
			} else {
				resultMap.put("code", "0");
				resultMap.put("msg", "商品状态更新失败，请重试！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "-1");
			resultMap.put("msg", "商品状态更新失败，请重试！");
		}
		return resultMap;
	}

	/**
	 * 删除商品
	 * 
	 * @Title: saveProductPrice
	 * @Description:(描述)
	 * @param request
	 * @param product
	 * @return Map<String,Object>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月3日 下午4:14:59
	 */
	@RequestMapping(value = "/doDelPro")
	@ResponseBody
	public Map<String, Object> doDelPro(HttpServletRequest request, Long productId) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			if (StringUtil.isNotNull(productId)) {
				int rows = productService.deleteProductById(productId);
				if (rows > 0) {
					resultMap.put("code", "1");
					resultMap.put("msg", "商品已删除成功！");
				} else {
					resultMap.put("code", "0");
					resultMap.put("msg", "商品删除失败！");
				}
			} else {
				resultMap.put("code", "0");
				resultMap.put("msg", "商品删除失败，请重试！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "-1");
			resultMap.put("msg", "商品价删除异常，请重试！");
		}
		return resultMap;
	}

	/**
	 * 跳转详情
	 * 
	 * @param request
	 * @param model
	 * @return String
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年12月11日 下午5:45:14
	 */
	@RequestMapping(value = "/toDetail")
	public String toDetailPage(HttpServletRequest request, Model model) {
		// 编辑操作
		long id = Long.valueOf(request.getParameter("id"));
		try {
			ProductEntity product = productService.getProductById(id);
			// 获取商品分类名称
			ProductCategoryEntity productCategory = productCategoryService.getProductCategoryById(product.getProductCategoryId());
			product.setProductCategoryName((null != productCategory ? productCategory.getCategoryName() : null));
			// // 图文描述的图片地址替换 TEMPPATH换成路径
			// if (StringUtil.isNotNull(product.getProductIntro())) {
			// String productIntro =
			// product.getProductIntro().replaceAll("TEMPPATH",
			// PublicConfig.IMG_ROOT_URL);
			// product.setProductIntro(productIntro);
			// }
			List<ProductImageEntity> imgList = productImageService.listProductImage(product.getId(), null);
			model.addAttribute("imgList", imgList);
			// 获取商品已有属性
			List<ProductPropertyRelaEntity> propertyList = productPropertyRelaService.listProductPropertyRela(id);
			model.addAttribute("propertyList", propertyList);
			String properties = "";
			for (ProductPropertyRelaEntity property : propertyList) {
				properties += SysSymbol.COMMA + property.getId() + SysSymbol.NUMBER_SIGN + property.getPropertyName() + SysSymbol.NUMBER_SIGN
				        + property.getPropertyValue();
				product.setPropertyTmeplateId(String.valueOf(property.getPropertyTmeplateId()));
			}
			product.setProperties(properties);
			// 商品标签
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("status", STATUS.ENABLED.getId());
			List<ProductTagEntity> productTagList = productTagService.listProductTag(param);
			model.addAttribute("productTagList", productTagList);
			// 活动标签.
			// List<KeyMapEntity> promotionTagList =
			// keyMapService.listKeyMap("promotionTag");
			List<PromotionTagEntity> promotionTagList = promotionTagService.listPromotionTag(param);
			model.addAttribute("promotionTagList", promotionTagList);
			// 商品状态
			List<KeyMapEntity> productStatusList = keyMapService.listKeyMap("productStatus");
			model.addAttribute("productStatusList", productStatusList);
			// 组装数据
			doFullData(model, id);
			request.setAttribute("product", product);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "product/product_detail";

	}

	/**
	 * 跳转编辑页面
	 * 
	 * @return string 跳转页面路径
	 * @author xu_cc
	 * @date 2017-08-29 20:09:14
	 */
	@RequestMapping("/toUpdateProduct")
	public String toUpdateProduct(HttpServletRequest request, Model model) {
		request.setAttribute("opFlag", "edit");
		// 编辑操作
		long id = Long.valueOf(request.getParameter("id"));
		try {
			ProductEntity product = productService.getProductById(id);
			// 获取商品分类名称
			ProductCategoryEntity productCategory = productCategoryService.getProductCategoryById(product.getProductCategoryId());
			product.setProductCategoryName((null != productCategory ? productCategory.getCategoryName() : null));
			// // 图文描述的图片地址替换 TEMPPATH换成路径
			// if (StringUtil.isNotNull(product.getProductIntro())) {
			// String productIntro =
			// product.getProductIntro().replaceAll("TEMPPATH",
			// PublicConfig.IMG_ROOT_URL);
			// product.setProductIntro(productIntro);
			// }
			List<ProductImageEntity> imgList = productImageService.listProductImage(product.getId(), null);
			model.addAttribute("imgList", imgList);
			// 获取商品已有属性
			List<ProductPropertyRelaEntity> propertyList = productPropertyRelaService.listProductPropertyRela(id);
			model.addAttribute("propertyList", propertyList);
			String properties = "";
			for (ProductPropertyRelaEntity property : propertyList) {
				properties += SysSymbol.COMMA + property.getId() + SysSymbol.NUMBER_SIGN + property.getPropertyName() + SysSymbol.NUMBER_SIGN
				        + property.getPropertyValue();
				product.setPropertyTmeplateId(String.valueOf(property.getPropertyTmeplateId()));
			}
			product.setProperties(properties);
			// 商品标签
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("status", STATUS.ENABLED.getId());
			List<ProductTagEntity> productTagList = productTagService.listProductTag(param);
			model.addAttribute("productTagList", productTagList);
			// 活动标签
			List<PromotionTagEntity> promotionTagList = promotionTagService.listPromotionTag(param);
			model.addAttribute("promotionTagList", promotionTagList);
			// 商品状态
			List<KeyMapEntity> productStatusList = keyMapService.listKeyMap("productStatus");
			model.addAttribute("productStatusList", productStatusList);
			// 组装数据
			doFullData(model, id);
			request.setAttribute("product", product);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "product/product_form";
	}

	/**
	 * 跳转商品编辑页面，首先获取选择规格信息
	 * 
	 * @param model
	 * @param productId
	 *            void
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月16日 下午4:09:51
	 */
	private void doFullData(Model model, Long productId) {
		// 获取选中规格
		List<ProductSpecRelaEntity> productSpecRelaList = productService.listProductSpecRelaList(productId);
		// model.addAttribute("productSpecRelaList", productSpecRelaList);
		// 解析选中的规格名称
		Set<String> specRelaSet = new HashSet<String>();
		if (null != productSpecRelaList && productSpecRelaList.size() > 0) {
			StringBuffer productSpecChose = new StringBuffer();
			for (ProductSpecRelaEntity psr : productSpecRelaList) {
				productSpecChose.append(psr.getSpecName()).append(SysSymbol.NUMBER_SIGN).append(psr.getSpecValue()).append(SysSymbol.NUMBER_SIGN)
				        .append(psr.getSpecId()).append(SysSymbol.COMMA);
				specRelaSet.add(psr.getSpecName());
			}
			model.addAttribute("productSpecChose", productSpecChose.toString());
			StringBuffer columnsStr = new StringBuffer();
			for (String setStr : specRelaSet) {
				columnsStr.append(setStr).append(SysSymbol.NUMBER_SIGN);
			}
			model.addAttribute("specRelaColumns", columnsStr.toString());
		}
		// 获取
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("productId", productId);
		List<ProductSpecCompositionEntity> prcLst = productSpecCompositionService.listProductSpecComposition(paramMap);
		if (null != prcLst && prcLst.size() > 0) {
			JSONArray array = new JSONArray();
			for (ProductSpecCompositionEntity psc : prcLst) {
				JSONObject jsonObj = JSONObject.parseObject(psc.getSpecComposition());
				array.add(jsonObj);
			}
			model.addAttribute("specRelaRows", JSONUtils.toJsonString(array));
		}
	}

	/**
	 * 上传单个或多个文件（Ueditor）
	 * 
	 * @param request
	 * @param response
	 * @author yaoyu
	 * @date 2017年4月21日 上午10:40:27
	 */
	@RequestMapping(value = "/uploadMultiFile", produces = "text/html;charset=UTF-8")
	public void uploadMultiFile(HttpServletRequest request, HttpServletResponse response) {
		MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
		Map<String, MultipartFile> fileMap = multipartHttpServletRequest.getFileMap();
		Set<String> keySet = fileMap.keySet();
		Iterator<String> iterator = keySet.iterator();
		PrintWriter out = null;
		try {
			out = response.getWriter();
			while (iterator.hasNext()) {
				String key = iterator.next();
				MultipartFile multipartFile = fileMap.get(key);
				// 源文件名
				String originalFilename = multipartFile.getOriginalFilename();
				// 后缀名
				String extName = FilenameUtils.getExtension(originalFilename);
				// 获取自增序列
				Long seqId = new Date().getTime();
				// 文件重新命名
				String newFileName = com.solution.common.utils.DateUtils.getDate("yyyyMMddHHmmssSSS") + seqId + "." + extName;
				// 上传
				InputStream is = multipartFile.getInputStream();
				String filePath = OssUploadFile.uploadFileToAliyun(is, newFileName, multipartFile.getSize());
				JSONObject result = new JSONObject();
				result.put("url", filePath);
				result.put("type", extName);
				out.print(result.toJSONString());
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				out.flush();
				out.close();
			}
		}
	}

	/**
	 * 编辑器
	 * 
	 * @Title: multiFileUeditorUpload
	 * @Description:(描述)
	 * @param request
	 * @param response
	 *            void
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年9月3日 下午5:18:36
	 */
	@RequestMapping(value = "/multiFileUeditorUpload")
	public void multiFileUeditorUpload(HttpServletRequest request, HttpServletResponse response) {
		MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
		Map<String, MultipartFile> fileMap = multipartHttpServletRequest.getFileMap();
		Set<String> keySet = fileMap.keySet();
		Iterator<String> iterator = keySet.iterator();
		PrintWriter out = null;
		try {
			out = response.getWriter();
			while (iterator.hasNext()) {
				String key = iterator.next();
				MultipartFile multipartFile = fileMap.get(key);
				// 源文件名
				String originalFilename = multipartFile.getOriginalFilename();
				// 后缀名
				String extName = FilenameUtils.getExtension(originalFilename);
				// 文件重新命名
				String name = UUID.randomUUID().toString().replaceAll("-", "");
				String newFileName = name + "." + extName;
				// 上传
				InputStream is = multipartFile.getInputStream();
				String filePath = OssUploadFile.uploadFileToAliyun(is, newFileName, multipartFile.getSize());
				JSONObject result = new JSONObject();
				result.put("url", filePath);
				result.put("type", extName);
				result.put("name", name);
				result.put("url", PublicConfig.IMG_ROOT_URL + filePath);
				result.put("saveurl", filePath);
				result.put("state", "SUCCESS");
				result.put("type", extName);
				result.put("ftp", PublicConfig.IMG_ROOT_URL + filePath);
				out.print(result.toJSONString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 复制商品
	 * 
	 * @param request
	 * @param productId
	 * @return
	 * @author xkl
	 * @date 2017年12月19日 下午7:07:01
	 */
	@RequestMapping("/copyProduct")
	@ResponseBody
	public BaseReturn copyProduct(HttpServletRequest request, Long productId) {
		BaseReturn result = new BaseReturn();
		try {
			// 序列号
			String seqCode = sequenceService.getSequenceNumber(SequenceRedisKey.REDIS_SEQ_PRODUCT, SequenceLength.LENGTH_PRODUCT);
			Long copyProductId = productService.copyProduct(productId, "SP" + seqCode);
			ProductEntity copyProduct = productService.getProductById(copyProductId);
			/* 积分商品所属商品分类 */
			String pointProductCategoryIdStr = PublicConfigUtil.readConfig("point.product.category.id");
			copyProduct.setIsPointProduct(0);
			if(StringUtil.isNotNull(pointProductCategoryIdStr)) {
				Long pointProductCategoryId = Long.parseLong(pointProductCategoryIdStr);
				ProductCategoryEntity productCategory = productCategoryService.getProductCategoryById(copyProduct.getProductCategoryId());
				if(null != productCategory && (productCategory.getId().equals(pointProductCategoryId) || productCategory.getParentCategoryId().equals(pointProductCategoryId))) {
					copyProduct.setIsPointProduct(1);
				}
			}
			if(copyProduct.getIsPointProduct().equals(0)) {
				int sortNo = sortService.getFirstSortNo("EB_PRODUCT");
				copyProduct.setSortNo(sortNo);// 默认排序号
				int quotaSortNo = sortService.getMaxSortNo("EB_PRODUCT");
				copyProduct.setQuotaSortNo(quotaSortNo);// 默认排序号
			} else {
				int sortNo = sortService.getMaxSortNo("EB_PRODUCT");
				copyProduct.setSortNo(sortNo);// 默认排序号
				copyProduct.setQuotaSortNo(sortNo);// 默认排序号
			}
//			if(copyProduct.getIsPointProduct().equals(0)) {
//				sortService.sort("1", "EB_PRODUCT", copyProductId, null, null);
//			} else {
//				sortService.sort("100", "EB_PRODUCT", copyProductId, null, null);
//			}
			productService.updateProduct(copyProduct);
			result.setData(copyProductId);
			result.setCode(SysCode.SUCCESS);
			result.setMsg("复制商品成功！");
		} catch (Exception e) {
			result.setCode(SysCode.ERROR);
			result.setMsg("复制商品异常！");
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 导出商品排序模板
	 * 
	 * @param request
	 * @param response
	 * @param product
	 *            void
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2018年4月27日 上午11:48:38
	 */
	@RequestMapping("/expProductSort")
	public void expProductSort(HttpServletRequest request, HttpServletResponse response, ProductEntity product) {
		try {
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("productCode", product.getProductCode());
			paramMap.put("productName", product.getProductName());
			paramMap.put("brandCode", product.getBrandCode());
			paramMap.put("productCategoryId", product.getProductCategoryId());
			paramMap.put("promotionTag", product.getPromotionTag());
			paramMap.put("productStatus", product.getProductStatus());
			List<ProductEntity> productList = productService.listProduct(paramMap);

			List<String> headNames = new ArrayList<String>();
			headNames.add("商品编码");
			headNames.add("商品名称");
			headNames.add("商品分类");
			headNames.add("品牌名称");
			headNames.add("游客价");
			headNames.add("显示权重");
			headNames.add("商品排序");
			headNames.add("报价单排序");

			List<String> fieldNames = new ArrayList<String>();
			fieldNames.add("productCode");
			fieldNames.add("productName");
			fieldNames.add("productCategoryName");
			fieldNames.add("brandName");
			fieldNames.add("touristPrice");
			fieldNames.add("sortWeight");
			fieldNames.add("sortNo");
			fieldNames.add("quotaSortNo");

			List<Map<String, Object>> dataMap = null;
			if (null != productList && productList.size() > 0) {
				dataMap = new ArrayList<Map<String, Object>>();
				for (ProductEntity pro : productList) {
					Map<String, Object> proMap = new HashMap<String, Object>();
					proMap.put("productCode", pro.getProductCode());
					proMap.put("productName", pro.getProductName());
					proMap.put("productCategoryName", pro.getProductCategoryName().replaceAll("\\|", " / "));
					proMap.put("brandName", pro.getBrandName());
					proMap.put("touristPrice", pro.getTouristPrice());
					proMap.put("sortWeight", pro.getSortWeight());
					proMap.put("sortNo", pro.getSortNo());
					proMap.put("quotaSortNo", pro.getQuotaSortNo());
					dataMap.add(proMap);
				}
			}
			String fileName = "商品排序模版_" + UUIDUtil.generateInteger(6) + ".xlsx";
			expToExcel07(request, response, headNames, fieldNames, fileName, dataMap);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	
	
	
	/**
	 * 导入商品排序
	 * 
	 * @param request
	 * @param response
	 * @param model
	 * @param multfile
	 * @return String
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2018年4月27日 下午2:26:12
	 */
	@RequestMapping("/impProductSort")
	public String impProductSort(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam("file") MultipartFile multfile) {
		StringBuffer msg = new StringBuffer();
		try {
			msg = doCheck(multfile);
			if (StringUtil.isNotNull(msg.toString())) {
				return toListPageFromUpload(model, msg.toString());
			}
			List<Map<String, String>> mapList = null;
			try {
				// 先以xlsx，poi读取2007的方式读取
				mapList = ExcelUtil.readSheet2007(multfile, 0);
				if (null == mapList) {
					// 以2003，xls，jxl的方式读取
					File file = ExcelUtil.multipartToFile(multfile);
					mapList = ExcelUtil.readSheet(file, 0);
				}
			} catch (Exception e) {
				msg.append("文件读取数据异常！" + e.getMessage());
				e.printStackTrace();
			}
			if (null != mapList && mapList.size() > 0) {
				// 正常title
				Map<String, String> headMap = new HashMap<String, String>();
				headMap.put("商品编码", "商品编码");
				headMap.put("商品名称", "商品名称");
				headMap.put("商品分类", "商品分类");
				headMap.put("品牌名称", "品牌名称");
				headMap.put("游客价", "游客价");
				headMap.put("显示权重", "显示权重");
				headMap.put("商品排序", "商品排序");
				headMap.put("报价单排序", "报价单排序");
				// 读取到的title
				Map<String, String> titleMap = mapList.get(0);
				// 标题校验
				for (String key : headMap.keySet()) {
					if (!titleMap.containsKey(key)) {
						msg.append("标题校验失败，请上传正确的文件！");
						return toListPageFromUpload(model, msg.toString());
					}
				}
				// 标题校验成功，开始提取数据组装
				List<ProductEntity> productList = doGetDataFromMapList(mapList, msg);
				// 如果错误有错误信息，直接返回页面
				if (StringUtil.isNotNull(msg.toString())) {
					toListPageFromUpload(model, msg.toString());
				} else {
					// 开始执行导入数据
					doExecDataToDB(productList, msg);
				}
			} else {
				msg.append("未读取到数据！");
			}
		} catch (Exception e) {
			msg.append("文件导入异常！" + e.getMessage());
			e.printStackTrace();
		}
		return toListPageFromUpload(model, msg.toString());
	}

	/**
	 * 上传操作转回列表页
	 * 
	 * @param model
	 * @param msg
	 * @return String
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2017年10月27日 下午3:36:24
	 */
	private String toListPageFromUpload(Model model, String msg) {
		try {
			// 保存错误信息
			model.addAttribute("msg", msg.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "product/product_list";
	}

	/**
	 * 数据导入到数据库中
	 * 
	 * @param productList
	 * @param msg
	 *            void
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2018年4月27日 下午3:07:36
	 */
	private void doExecDataToDB(List<ProductEntity> productList, StringBuffer msg) {
		if (null != productList && productList.size() > 0) {
			for (int i = 0; i < productList.size(); i++) {
				ProductEntity product = productList.get(i);
				try {
					productService.updateProductSortNo(product);
					msg.append("第").append(i + 1).append("行导入成功！商品编码：").append(product.getProductCode()).append("<br/>");
				} catch (Exception e) {
					msg.append("<b>第").append(i + 1).append("行导入失败！商品编码：").append(product.getProductCode()).append("</b><br/>");
					e.printStackTrace();
				}
			}
		} else {
			msg.append("未获取到数据！");
		}
	}

	/**
	 * 组装数据
	 * 
	 * @param mapList
	 * @param msg
	 * @return List<ProductEntity>
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2018年4月27日 下午3:06:34
	 */
	private List<ProductEntity> doGetDataFromMapList(List<Map<String, String>> mapList, StringBuffer msg) {
		List<ProductEntity> productList = new ArrayList<ProductEntity>();
		ProductEntity product = null;
		String userName = getUserName();
		boolean isOk = true;
		
		// 显示权重集合
		List<KeyMapEntity> keyMapList = keyMapService.listKeyMap("sortWeight");
		Set<String> set = new HashSet<>();
		String allowSortWeightValue = "";
		if(null != keyMapList && keyMapList.size() > 0) {
			for (KeyMapEntity keyMap : keyMapList) {
				set.add(keyMap.getKeyValue());
				allowSortWeightValue += keyMap.getKeyValue() + "；";
            }
		} else {
			msg.append("尚未配置“显示权重”字典，key值：sortWeight，请联系运营人员维护！");
			return null;
		}
		for (int i = 0; i < mapList.size(); i++) {
			isOk = true;
			// 获取数据
			Map<String, String> dataMap = mapList.get(i);
			String productCode = dataMap.get("商品编码");
			String productName = dataMap.get("商品名称");
			String productCategoryName = dataMap.get("商品分类");
			String sortWeightStr = dataMap.get("显示权重");
			String sortNoStr = dataMap.get("商品排序");
			String quatoSortNoStr = dataMap.get("报价单排序");
			// 行信息
			String rowInfo = StringUtil.formatString("【商品编码：%s，商品名称：%s，商品分类：%s】", productCode, productName, productCategoryName);

			if (StringUtil.isEmpty(productCode)) {
				msg.append("第").append(i + 1).append("行 ").append(rowInfo).append(" 商品编码 为空！<br/>");
				isOk = false;
			}
			if(StringUtil.isNotNull(sortWeightStr)) {
				if (!StringUtil.isNumeric(sortWeightStr) || (sortWeightStr.length() > 11)) {
					msg.append("第").append(i + 1).append("行 ").append(rowInfo).append(" 显示权重 不是数字或长度过长[最长6位数]！<br/>");
					isOk = false;
				}
				if(!set.contains(sortWeightStr)) {
					msg.append("第").append(i + 1).append("行 ").append(rowInfo).append(" 显示权重 输入错误，数值范围应该是").append(allowSortWeightValue).append("<br/>");
					isOk = false;
				}
			}
			if(StringUtil.isNotNull(sortNoStr)) {
				if (!StringUtil.isNumeric(sortNoStr) || (sortNoStr.length() > 11)) {
					msg.append("第").append(i + 1).append("行 ").append(rowInfo).append(" 商品排序 不是数字或长度过长[最长 11 位数]！<br/>");
					isOk = false;
				}
			}
			if(StringUtil.isNotNull(quatoSortNoStr)) {
				if (!StringUtil.isNumeric(quatoSortNoStr) || (quatoSortNoStr.length() > 11)) {
					msg.append("第").append(i + 1).append("行 ").append(rowInfo).append(" 报价单排序 不是数字或长度过长[最长 11 位数]！<br/>");
					isOk = false;
				}
			}
			// 读取行成功
			if (isOk) {
				// 是否比较行信息与数据信息
				product = new ProductEntity();
				product.setProductCode(productCode);
				product.setSortWeight(StringUtil.isNotNull(sortWeightStr) ? Integer.parseInt(sortWeightStr) : null);
				product.setSortNo(StringUtil.isNotNull(sortNoStr) ? Integer.parseInt(sortNoStr) : null);
				product.setQuotaSortNo(StringUtil.isNotNull(quatoSortNoStr) ? Integer.parseInt(quatoSortNoStr) : null);
				product.setCreater(userName);
				product.setModifier(userName);
				productList.add(product);
			} else {
				msg.append("第").append(i + 1).append("行读取数据失败！<br/>");
				continue;
			}
		}
		return productList;
	}

	/**
	 * 校验文件
	 * 
	 * @param file
	 * @return StringBuffer
	 * @author xu_cc
	 * @throws Exception
	 *             exception
	 * @Date 创建时间：2018年4月27日 下午3:06:46
	 */
	private StringBuffer doCheck(MultipartFile file) {
		StringBuffer msg = new StringBuffer();
		if (null == file) {
			msg.append("未获取到传入文件内容！<br/>");
			return msg;
		}
		if (!file.getOriginalFilename().matches("^.+\\.(?i)(xlsx)$") && !file.getOriginalFilename().matches("^.+\\.(?i)(xls)$")) {
			msg.append("请传入xlsx 或 xls格式的文件！<br/>");
			return msg;
		}
		if (file.getSize() == 0) {
			msg.append("错误文件(可能是非Excel文件改后缀名导致)！<br/>");
			return msg;
		}
		if (file.getSize() > (2 * 1048576)) {
			msg.append("文件大小限制为2M！<br/>");
			return msg;
		}
		return msg;
	}
}
